<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'

defineOptions({
  name: 'SafeTopContainer',
})

const props = withDefaults(defineProps<Props>(), {
  paddingBottom: 15,
})

interface Props {
  fixed?: boolean
  bgColor?: string
  showBgColor?: boolean
  showPlaceholder?: boolean
  paddingLeft?: number
  paddingRight?: number
  paddingBottom?: number
}

// 胶囊信息
const capsuleTop = ref<number>(0)
const capsuleWidth = ref<number>(0)
const capsuleHeight = ref<number>(0)
const capsuleLeft = ref<number>(0)
const capsuleRight = ref<number>(0)

// 判断平台
const isH5 = typeof window !== 'undefined' && typeof document !== 'undefined'

// 检测是否是iPhone刘海屏
function isIphoneWithNotch(): boolean {
  if (!isH5)
    return false
  const ua = window.navigator.userAgent
  const isIphone = /iPhone/.test(ua)
  if (!isIphone)
    return false

  // 屏幕尺寸+比例判断（常用判断方法）
  const { width, height } = window.screen
  const ratio = window.devicePixelRatio

  const notchScreens = [
    { width: 375, height: 812, ratio: 3 }, // iPhone X, XS, 11 Pro
    { width: 414, height: 896, ratio: 2 }, // iPhone XR, 11
    { width: 414, height: 896, ratio: 3 }, // iPhone XS Max, 11 Pro Max
    { width: 390, height: 844, ratio: 3 }, // iPhone 12, 12 Pro, 13, 13 Pro
    { width: 428, height: 926, ratio: 3 }, // iPhone 12 Pro Max, 13 Pro Max
    { width: 393, height: 852, ratio: 3 }, // iPhone 14, 15, 15 Pro
    { width: 430, height: 932, ratio: 3 }, // iPhone 14 Pro Max, 15 Pro Max
  ]

  return notchScreens.some(
    screen =>
      (screen.width === width && screen.height === height && screen.ratio === ratio)
      || (screen.width === height && screen.height === width && screen.ratio === ratio),
  )
}

// 固定布局样式
const fixedLayoutStyle = computed(() => ({
  width: '100%',
  paddingTop: `${capsuleTop.value}px`,
  paddingBottom: `${props.paddingBottom}rpx`,
  background: props.showBgColor ? props.bgColor : 'transparent',
}))

// 外层盒子样式
const outerBoxStyle = computed(() => ({
  width: '100%',
  height: `${capsuleHeight.value}px`,
  position: 'relative',
}))

// 内层盒子样式
const innerBoxStyle = computed(() => ({
  width: '100%',
  paddingLeft: `${props.paddingLeft}px`,
  paddingRight: `${props.paddingRight}px`,
  position: 'absolute',
  top: '50%',
  transform: 'translateY(-50%)',
}))

onMounted(() => {
  try {
    if (!isH5) {
      const capsuleInfo = uni.getMenuButtonBoundingClientRect()
      console.log(capsuleInfo)
      if (!capsuleInfo || !capsuleInfo.height) {
        throw new Error('胶囊信息异常')
      }
      capsuleTop.value = capsuleInfo.top
      capsuleWidth.value = capsuleInfo.width
      capsuleHeight.value = capsuleInfo.height
      capsuleLeft.value = capsuleInfo.left
      capsuleRight.value = capsuleInfo.right

      console.log('《TopSafeArea》小程序端胶囊信息:', capsuleInfo)
    }
    else {
      // H5环境
      const statusBarHeight = isIphoneWithNotch() ? 44 : 20
      const navBarHeight = 44
      capsuleTop.value = statusBarHeight
      capsuleHeight.value = navBarHeight
      capsuleWidth.value = 100
      capsuleLeft.value = window.innerWidth - capsuleWidth.value - 10
      capsuleRight.value = window.innerWidth - 10

      console.log('《TopSafeArea》H5端默认胶囊信息:', {
        top: capsuleTop.value,
        height: capsuleHeight.value,
      })
    }
  }
  catch (error) {
    console.error('获取胶囊信息失败，使用默认值', error)
    capsuleTop.value = 20
    capsuleHeight.value = 32
  }
})
</script>

<template>
  <view class="safe-top-container" :style="fixedLayoutStyle" :class="{ 'fixed-wrapper': props.fixed }">
    <view class="outer-box" :style="outerBoxStyle">
      <view class="inner-box" :style="innerBoxStyle">
        <slot />
      </view>
    </view>
  </view>

  <!-- 占位盒子，防止内容被遮挡 -->
  <view v-if="props.fixed && props.showPlaceholder" :style="{ height: `${capsuleTop + capsuleHeight}px` }" />
</template>

<style scoped lang="scss">
.safe-top-container {
  width: 100%;
}

.fixed-wrapper {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  z-index: 998;
}

.outer-box {
  width: 100%;
  position: relative;
}

.inner-box {
  width: 100%;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
</style>
